package cn.cas.mango.service.samenews;


import cn.cas.mango.dto.HotSpotNews;

import cn.cas.mango.util.ResponseUtil.ResponseUtil;
import cn.cas.mango.util.dbscanHot.DBSCAN;
import cn.cas.mango.util.dbscanHot.Data;
import co.elastic.clients.elasticsearch.core.search.Hit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SameHotNewsService {
  private final Map<String, Hit<HotSpotNews>> cast = new HashMap<>();
  private final List<Hit<HotSpotNews>> hits;
  public SameHotNewsService(List<Hit<HotSpotNews>> hits) {
    this.hits = hits;
  }
  private void generateCast()  {
    for (Hit<HotSpotNews> hit: hits) {
      cast.put(hit.source().getId(), hit);
    }
  }

  private Map<String, List<String>> runDBSCAN(List<Hit<HotSpotNews>> hits, double factor, double entityFactor) {
    List<Data> rawAllData = new ArrayList<>();
    for (Hit<HotSpotNews> hit1: hits) {
      rawAllData.add(wrappedData(hit1));
    }
    try {
      return new DBSCAN(rawAllData).run(factor);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return new HashMap<>();
  }

  private Data wrappedData(Hit<HotSpotNews> hit) {
    assert hit.source() != null;
    String id = hit.source().getId();
    HotSpotNews news = hit.source();
    assert news != null;
    Set<String> keywords = ResponseUtil.wrappedKeyword(news.getNewsKeywords());
    Set<String> entities = ResponseUtil.wrappedKeyword(news.getNewsEntities());
    // 如果新闻时间空缺，指定一个默认时间
    String date = "2010-02-02";
    if (news.getNewsPublicDate() != null) {
      date = news.getNewsPublicDate();
    }
    return new Data(id, keywords, entities, date);
  }

  public Map<String, List<Hit<HotSpotNews>>> getSameNewsList(double factor, double entitiesFactor) {
    generateCast();
    Map<String, List<String>> map = runDBSCAN(hits, factor, entitiesFactor);
    Map<String, List<Hit<HotSpotNews>>> ret = new LinkedHashMap<>();
    for (String key: map.keySet()) {
      ret.put(key, new ArrayList<>());
      for (String string: map.get(key)) {
        ret.get(key).add(cast.get(string));
      }
    }
    return ret;
  }

}
